﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Empires.PL.PageBuilder
{
    /// <summary>
    /// html文件中head段解析器
    /// </summary>
    class HeadAnalyzer
    {
        /// <summary>
        /// 解析入口
        /// </summary>
        /// <param name="rawheadtext">待解析元素head段</param>
        /// <param name="templetePath">模板相对路径（/WebTemplete/SystemTemplete/LawFirm）</param>
        /// <returns></returns>
        public static string Analysis(string rawheadtext, string templetePath, string copName)
        {
            string righttitleandkeyword = CorrectionTitleAndKeyWord(rawheadtext, copName);
            string rightsrc = CorrectionSrc(righttitleandkeyword, templetePath);
            string righthref = Correctionhref(rightsrc, templetePath);
            //return CorrectionJSCoding(righthref, templetePath);
            return righthref;
        }
        static string CorrectionTitleAndKeyWord(string rawheadtext, string copName)
        {
            string titleandkeyword = PL.ServiceClient.CompanySettingServiceClient.GetTitleAndKeyWord(copName);
            string title = String.Format("<title>{0}</title>", titleandkeyword.Split('$')[0]);
            string keyword = String.Format("<meta name=\"keywords\" content=\"{0}\" />", titleandkeyword.Split('$')[1]);
            Regex reg = new Regex(PageBuilderRegexpLib.Keywordspicker, RegexOptions.IgnoreCase);
            if (reg.IsMatch(rawheadtext))
            {
                rawheadtext = reg.Replace(rawheadtext, keyword);
            }
            else
            {
                rawheadtext = keyword + "*r*n" + rawheadtext;
            }
             reg = new Regex(PageBuilderRegexpLib.TitlePicker, RegexOptions.IgnoreCase);
            if (reg.IsMatch(rawheadtext))
            {
                rawheadtext = reg.Replace(rawheadtext, title);
            }
            else
            {
                rawheadtext = title + "*r*n" + rawheadtext;
            }
          
            return rawheadtext;
        }
        /// <summary>
        /// 修正head中src连接
        /// </summary>
        /// <param name="rawheadtext">待解析元素head段</param>
        /// <param name="templetePath"></param>
        /// <returns></returns>
        static string CorrectionSrc(string rawheadtext, string templetePath)
        {
            Regex reg = new Regex(PageBuilderRegexpLib.SrcPicker, RegexOptions.IgnoreCase);
            MatchCollection matchs = reg.Matches(rawheadtext);
            int addindex = 0;
            foreach (Match item in matchs)
            {
                string path = item.ToString().Replace("/","\\");
                if (String.IsNullOrEmpty(path))
                {
                    continue;
                }
                if (path.Contains(".."))
                {
                    List<string> piece = path.Split('\\').ToList();
                    int pevtimes = piece.Where(c => c == "..").Count();
                    System.IO.DirectoryInfo dir = new System.IO.FileInfo(templetePath).Directory;
                    for (int i = 0; i < pevtimes; i++)
                    {
                        dir = dir.Parent;
                    }
                    string currentPath = dir.FullName.EndsWith("\\") ? dir.FullName : dir.FullName + "\\";
                    if (!currentPath.Contains(AppDomain.CurrentDomain.SetupInformation.ApplicationBase))
                    {
                        rawheadtext = reg.Replace(rawheadtext, "javascript:;", 1, item.Index + addindex);
                        addindex += currentPath.Length - path.Length;
                    }
                    else
                    {
                        currentPath = currentPath.Replace(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "");
                        currentPath += Concat(piece.Where(c => c != "..").ToList());
                        rawheadtext = reg.Replace(rawheadtext, currentPath.StartsWith("\\") ? currentPath : "\\" + currentPath, 1, item.Index + addindex);
                        addindex += currentPath.Length - path.Length;
                    }
                }
                else
                {
                    System.IO.DirectoryInfo dir = new System.IO.FileInfo(templetePath).Directory;
                    string currentPath = dir.FullName.EndsWith("\\") ? dir.FullName : dir.FullName + "\\";
                    currentPath = currentPath.Replace(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "");
                    if (currentPath.EndsWith("\\"))
                    {
                        if (path.StartsWith("\\"))
                        {
                            currentPath += path.Substring(1);
                        }
                        else
                        {
                            currentPath += path;
                        }
                    }
                    else
                    {
                        if (path.StartsWith("\\"))
                        {
                            currentPath += path;
                        }
                        else
                        {
                            currentPath += "\\" + path;
                        }
                    }
                    rawheadtext = reg.Replace(rawheadtext, currentPath.StartsWith("\\") ? currentPath : "\\" + currentPath, 1, item.Index + addindex);
                    addindex += currentPath.Length - path.Length;
                }
            }
            return rawheadtext;
        }
        static string Concat(List<string> list)
        {
            StringBuilder sb = new StringBuilder();
            int length = list.Count;
            for (int i = 0; i < length; i++)
            {
                sb.Append(list[i]);
                if (i != length - 1)
                {
                    sb.Append("\\");
                }
            }
            return sb.ToString();
        }
        /// <summary>
        /// 解析head中href段
        /// </summary>
        /// <param name="rawheadtext"></param>
        /// <param name="templetePath"></param>
        /// <returns></returns>
        static string Correctionhref(string rawheadtext, string templetePath)
        {
            Regex reg = new Regex(PageBuilderRegexpLib.HrefPicker, RegexOptions.IgnoreCase);
            MatchCollection matchs = reg.Matches(rawheadtext);
            int addindex = 0;
            foreach (Match item in matchs)
            {
                string path = item.ToString().Replace("/", "\\");
                if (String.IsNullOrEmpty(path))
                {
                    continue;
                }
                if (path.Contains(".."))
                {
                    List<string> piece = path.Split('\\').ToList();
                    int pevtimes = piece.Where(c => c == "..").Count();
                    System.IO.DirectoryInfo dir = new System.IO.FileInfo(templetePath).Directory;
                    for (int i = 0; i < pevtimes; i++)
                    {
                        dir = dir.Parent;
                    }
                    string currentPath = dir.FullName.EndsWith("\\") ? dir.FullName : dir.FullName + "\\";
                    if (!currentPath.Contains(AppDomain.CurrentDomain.SetupInformation.ApplicationBase))
                    {
                        rawheadtext = reg.Replace(rawheadtext, "javascript:;", 1, item.Index + addindex);
                        addindex += currentPath.Length - path.Length;
                    }
                    else
                    {
                        currentPath = currentPath.Replace(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "");
                        currentPath += Concat(piece.Where(c => c != "..").ToList());
                        rawheadtext = reg.Replace(rawheadtext, currentPath.StartsWith("\\") ? currentPath : "\\" + currentPath, 1, item.Index + addindex);
                        addindex += currentPath.Length - path.Length;
                    }
                }
                else
                {
                    System.IO.DirectoryInfo dir = new System.IO.FileInfo(templetePath).Directory;
                    string currentPath = dir.FullName.EndsWith("\\") ? dir.FullName : dir.FullName + "\\";
                    currentPath = currentPath.Replace(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "");
                    if (currentPath.EndsWith("\\"))
                    {
                        if (path.StartsWith("\\"))
                        {
                            currentPath += path.Substring(1);
                        }
                        else
                        {
                            currentPath += path;
                        }
                    }
                    else
                    {
                        if (path.StartsWith("\\"))
                        {
                            currentPath += path;
                        }
                        else
                        {
                            currentPath += "\\" + path;
                        }
                    }
                    rawheadtext = reg.Replace(rawheadtext, currentPath.StartsWith("\\") ? currentPath : "\\" + currentPath, 1, item.Index + addindex);
                    addindex += currentPath.Length - path.Length;
                }
            }
            return rawheadtext;
        }
        /// <summary>
        /// 修正js中代码，添加只想模板路径的前缀。 目前只支持修改src和href属性，其他暂不做修改
        /// </summary>
        /// <param name="rawheadtext"></param>
        /// <param name="templetePath"></param>
        /// <returns></returns>
        public static string CorrectionJSCoding(string rawheadtext, string templetePath)
        {
            Regex reg = new Regex(PageBuilderRegexpLib.JqueryAttrPicker, RegexOptions.IgnoreCase);
            MatchCollection matchs = reg.Matches(rawheadtext);
            int addindex = 0;
            foreach (Match item in matchs)
            {
                string path = item.ToString().Replace("\\", "/");
                if (String.IsNullOrEmpty(path))
                {
                    continue;
                }
                string[] type = path.ToLower().Split(',').Select(c => c.Trim()).ToArray();
                switch (type[0])
                {
                    case "\"src\"":
                        #region src
                        if (type[1].Contains(".."))
                        {
                            List<string> piece = type[1].Split('/').ToList();
                            int pevtimes = piece.Where(c => c.Contains("..")).Count();
                            System.IO.DirectoryInfo dir = new System.IO.FileInfo(templetePath).Directory;
                            for (int i = 0; i < pevtimes; i++)
                            {
                                dir = dir.Parent;
                            }
                            string currentPath = dir.FullName.Replace("\\", "/").EndsWith("/") ? dir.FullName : dir.FullName + "/";
                            if (!currentPath.Contains(AppDomain.CurrentDomain.SetupInformation.ApplicationBase))
                            {   //防止超越app根目录
                                rawheadtext = reg.Replace(rawheadtext, "javascript:;", 1, item.Index + addindex);
                                addindex += currentPath.Length - path.Length;
                            }
                            else
                            {
                                currentPath = currentPath.Replace(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "");
                                currentPath += Concat(piece.Where(c => !c.Contains("..")).ToList()).Replace("\\", "/");
                                rawheadtext = reg.Replace(rawheadtext, type[0] + ",\"" + (currentPath.StartsWith("/") ? currentPath : "/" + currentPath), 1, addindex);
                                addindex += currentPath.Length - path.Length;
                            }
                        }
                        else
                        {
                            System.IO.DirectoryInfo dir = new System.IO.FileInfo(templetePath).Directory;
                            string currentPath = dir.FullName.EndsWith("/") ? dir.FullName : dir.FullName + "/";
                            currentPath = currentPath.Replace(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "");
                            if (currentPath.EndsWith("/"))
                            {
                                if (type[1].StartsWith("\"/"))
                                {
                                    currentPath += type[1].Substring(2);
                                }
                                else
                                {
                                    currentPath += type[1].Substring(1);
                                }
                            }
                            else
                            {
                                if (type[1].StartsWith("\"/"))
                                {
                                    currentPath += type[1].Substring(1);
                                }
                                else
                                {
                                    currentPath += "/" + type[1].Substring(1);
                                }
                            }
                            rawheadtext = reg.Replace(rawheadtext, type[0] + "," + (currentPath.StartsWith("\"/") ? currentPath.Replace("\\", "/") : "\"/" + currentPath.Replace("\\", "/")), 1, addindex);
                            addindex += currentPath.Length - path.Length;
                        }
                        #endregion
                        break;
                    case "\"href\"":
                        break;
                }
            }
            return rawheadtext;
        }
    }
}
